package com.nenglai.admin.modular.report.service.output;

import com.nenglai.admin.handler.RequestHolder;
import com.nenglai.admin.modular.report.enums.DocumentEnum;
import com.nenglai.model.report.entity.Download;
import com.nenglai.model.report.entity.Template;
import com.nenglai.report.Params;
import com.nenglai.report.service.OutputService;
import com.nenglai.report.util.WordDocxUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

/**
 * @author kongdehui
 * @date 2021/07/01 14:08
 **/
@Component("browserWordOutput")
public class BrowserWordOutput implements Output {

    @Resource
    OutputService outputService;

    @Override
    public Object output(Template template, File templateFile, Params params) throws Exception {
        FileInputStream in = new FileInputStream(templateFile);
        String suffix = template.suffix();
        if (DocumentEnum.DOCUMENT_TYPE_DOCX.getCode().equals(suffix)) {
            return docx(in, template, params, suffix);
        }

        if (DocumentEnum.DOCUMENT_TYPE_DOC.getCode().equals(suffix)) {
            return doc(in, template, params, suffix);
        }

        return null;
    }

    @Override
    public File download(Download download) {
        return null;
    }

    private Object doc(FileInputStream in, Template template, Params params, String suffix) throws IOException {
        HWPFDocument document = new HWPFDocument(in);
        Range range = document.getRange();
        for (Map.Entry<String, String> entry : params.getParagraphs().entrySet()) {
            String key = DocumentEnum.DOCUMENT_PARSING_BEGIN.getCode() + entry.getKey() + DocumentEnum.DOCUMENT_PARSING_END.getCode();
            range.replaceText(key, entry.getValue());
        }

        // 导出到浏览器
        String fileName = outputService.getOutputFilename(template.getFilePath(),
                StringUtils.isEmpty(params.getFilename()) ? template.getOutputTemplate() : params.getFilename());
        outputBrowser(in, document, fileName, RequestHolder.getResponse());

        return null;
    }

    private Object docx(FileInputStream in, Template template, Params params, String suffix)
            throws IOException {
        XWPFDocument doc = new XWPFDocument(in);
        // 替换段落中的指定文字
        WordDocxUtil.replaceInAllParagraphs(doc.getParagraphsIterator(), params.getParagraphs());
        // 替换表格中的指定文字
        WordDocxUtil.replaceInAllTables(doc.getTablesIterator(), params.getParagraphs());

        // 导出到浏览器
        String fileName = outputService.getOutputFilename(template.getFilePath(),
                StringUtils.isEmpty(params.getFilename()) ? template.getOutputTemplate() : params.getFilename());
        outputBrowser(in, doc, fileName, RequestHolder.getResponse());
        return null;
    }


    private void outputBrowser(FileInputStream in,
                               HWPFDocument doc,
                               String fileName,
                               HttpServletResponse response
    ) throws IOException {

        // 导出到浏览器
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream outStream = response.getOutputStream();

        try {
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(outStream);
            bufferedOutPut.flush();
            doc.write(bufferedOutPut);
            bufferedOutPut.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outStream != null) {
                outStream.close();
            }
            in.close();
            response.setStatus(200);
        }
    }

    private void outputBrowser(FileInputStream in,
                               XWPFDocument doc,
                               String fileName,
                               HttpServletResponse response
    ) throws IOException {

        // 导出到浏览器
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream outStream = response.getOutputStream();

        try {
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(outStream);
            bufferedOutPut.flush();
            doc.write(bufferedOutPut);
            bufferedOutPut.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outStream != null) {
                outStream.close();
            }
            in.close();
            response.setStatus(200);
        }
    }

}
